package ru.spb.osll.myfit.server.handler;

import org.easymock.EasyMock;
import org.easymock.EasyMockSupport;
import org.junit.Before;
import org.junit.Test;
import ru.spb.osll.myfit.common.Page;
import ru.spb.osll.myfit.common.Table;
import ru.spb.osll.myfit.server.parser.Constants;
import ru.spb.osll.myfit.server.parser.PageUtils;
import ru.spb.osll.myfit.util.CollectionUtils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;

import static org.junit.Assert.assertEquals;

public class ContentHandlerTest extends EasyMockSupport {
	private ContentHandler m_handler;
	private PageLoader loader;
	private ContentCreator creator;
	private final String SET_UP = ".SetUp";
	private final String TEAR_DOWN = ".TearDown";
	private String root = "FitNesseRoot";
    private ParentVariablesCreator variablesCreator;

	@Before
	public void setUp() throws SecurityException, NoSuchMethodException {
		Method readPageFileMethod = PageLoader.class.getMethod("readPageFile",  String.class);
		loader = createMockBuilder(PageLoader.class).withConstructor().addMockedMethods(readPageFileMethod).createMock();

		creator = createMock(ContentCreator.class);
		m_handler = new ContentHandler(root, loader, creator);

        Method getParentVariablesMap = ParentVariablesCreator.class.getMethod("getParentVariablesMap", String.class);
        variablesCreator = createMockBuilder(ParentVariablesCreator.class).withConstructor().addMockedMethod(getParentVariablesMap).createMock();
	}


//	@Test
//	public void testLoadPageWithInclude() throws IOException {
//		List<String> SimpleLoadList = CollectionUtils
//				.list("!include .TestInclude");
//		List<String> SimpleInckudeList = CollectionUtils
//				.list("|set node regeneration submit delay|30 min|");
//
//		String name = "PageWithImport";
//		EasyMock.expect(loader.readPageFile(getFullPath(name))).andReturn(SimpleLoadList);
//		EasyMock.expect(loader.readPageFile(getFullPath(SET_UP))).andThrow(
//				new FileNotFoundException(""));
//
//		EasyMock.expect(loader.readPageFile(getFullPath(TEAR_DOWN))).andThrow(
//				new FileNotFoundException(""));
//
//		String nameInclude = ".TestInclude";
//		EasyMock.expect(loader.readPageFile(getFullPath(nameInclude))).andReturn(
//				SimpleInckudeList);
//
//		replayAll();
//		Page page = m_handler.loadPage(name);
//
//		assertEquals(1, page.countPageElements());
//		assertEquals(PageElementType.INCLUDE.getKey(), page.getElement(0)
//				.getType().getKey());
//		Include include = (Include) page.getElement(0);
//		assertEquals(".TestInclude", include.getPath());
//		Page pageInclude = include.getPage();
//		assertEquals(1, pageInclude.countPageElements());
//		assertEquals(PageElementType.TABLE, pageInclude.getElement(0).getType());
//		verifyAll();
//	}

	@Test
	public void testLoadSimplePage() throws IOException {
		List<String> SimpleLoadList = CollectionUtils.list(
				"|set node regeneration submit delay|30 min|",
				Constants.LINE_SEPARATOR, "|with cubetools|",
				"|write|10|files of size|10KB|using|10|threads|");
		String name = "SimPlePage";

		EasyMock.expect(loader.readPageFile(getFullPath(name))).andReturn(SimpleLoadList);
		EasyMock.expect(loader.readPageFile(getFullPath(SET_UP))).andThrow(
				new FileNotFoundException(""));
		EasyMock.expect(loader.readPageFile(getFullPath(TEAR_DOWN))).andThrow(
				new FileNotFoundException(""));
//		EasyMock.replay(loader);

        HashMap<String, String> map = new HashMap<String,String>();
        EasyMock.expect(variablesCreator.getParentVariablesMap(getFullPath(name))).
                andReturn(map);
//        EasyMock.replay(variablesCreator);
        EasyMock.replay(loader, variablesCreator);

		Page page = m_handler.loadPage(name);
		EasyMock.verify(loader,variablesCreator);

		assertEquals(2, page.countPageElements());
		assertEquals("|set node regeneration submit delay|30 min|"
				+ Constants.LINE_SEPARATOR, PageUtils
				.tableToString((Table) page.getElement(0)));
		assertEquals("|with cubetools|" + Constants.LINE_SEPARATOR
				+ "|write|10|files of size|10KB|using|10|threads|"
				+ Constants.LINE_SEPARATOR, PageUtils
				.tableToString((Table) page.getElement(1)));


	}

//	@Test
//	public void testLoadPageWithImports() throws IOException {
//		List<String> SimpleLoadList = CollectionUtils.list("|Import|",
//				"|ru.spb.osll.myfit.examples|", Constants.LINE_SEPARATOR,
//				"|set node regeneration submit delay|30 min|");
//
//		String name = "PageWithImport";
//
//		EasyMock.expect(loader.readPageFile(getFullPath(name))).andReturn(SimpleLoadList);
//		EasyMock.expect(loader.readPageFile(getFullPath(SET_UP))).andThrow(
//				new FileNotFoundException(""));
//		EasyMock.expect(loader.readPageFile(getFullPath(TEAR_DOWN))).andThrow(
//				new FileNotFoundException(""));
//		EasyMock.replay(loader);
//
//		Page page = m_handler.loadPage(name);
//
//		assertEquals(1, page.countPageElements());
//		assertEquals("|set node regeneration submit delay|30 min|"
//				+ Constants.LINE_SEPARATOR, PageUtils
//				.tableToString((Table) page.getElement(0)));
//
//		EasyMock.verify(loader);
//	}
//
//	@Test
//	public void testLoadPageWithSetUp() throws IOException {
//
//	  List<String> SimpleLoadList = CollectionUtils.list(
//				"|set node regeneration submit delay|30 min|",
//				Constants.LINE_SEPARATOR, "|with cubetools|",
//				"|write|10|files of size|10KB|using|10|threads|",
//				Constants.LINE_SEPARATOR);
//		String name = "SimPlePage";
//
//		List<String> SimpleSetUp = CollectionUtils.list("|Import|",
//				"|ru.spb.osll.myfit.examples|", Constants.LINE_SEPARATOR,
//				"|with cubetools|",
//				"|write|1000000|files of size|10KB|using|80|threads|",
//				Constants.LINE_SEPARATOR);
//
//		EasyMock.expect(loader.readPageFile( getFullPath(name))).andReturn(SimpleLoadList);
//		EasyMock.expect(loader.readPageFile( getFullPath(SET_UP))).andReturn(SimpleSetUp);
//		EasyMock.expect(loader.readPageFile( getFullPath(TEAR_DOWN))).andThrow(
//				new FileNotFoundException(""));
//		EasyMock.replay(loader);
//		Page page = m_handler.loadPage(name);
//
//		assertEquals(3, page.countPageElements());
//		assertEquals(PageElementType.SET_UP, page.getElement(0).getType());
//
//		SetUp setUpinclude = (SetUp) page.getElement(0);
//		Page pageSetUp = setUpinclude.getPage();
//
//		assertEquals(1, pageSetUp.countPageElements());
//		assertEquals(PageElementType.TABLE, page.getElement(1).getType());
//		assertEquals("|set node regeneration submit delay|30 min|"
//				+ Constants.LINE_SEPARATOR, PageUtils
//				.tableToString((Table) page.getElement(1)));
//
//		assertEquals(PageElementType.TABLE, page.getElement(2).getType());
//
//		assertEquals("|with cubetools|" + Constants.LINE_SEPARATOR
//				+ "|write|10|files of size|10KB|using|10|threads|"
//				+ Constants.LINE_SEPARATOR, PageUtils
//				.tableToString((Table) page.getElement(2)));
//
//		EasyMock.verify(loader);
//	}
//
//	@Test
//	public void testLoadPageWithTearDown() throws IOException {
//		List<String> SimpleLoadList = CollectionUtils.list(
//				"|set node regeneration submit delay|30 min|",
//				Constants.LINE_SEPARATOR, "|with cubetools|",
//				"|write|10|files of size|10KB|using|10|threads|",
//				Constants.LINE_SEPARATOR);
//		String name = "SimPlePage";
//
//		List<String> SimpleTearnDown = CollectionUtils.list("|Import|",
//				"|ru.spb.osll.myfit.examples|", Constants.LINE_SEPARATOR,
//				"|with cubetools|",
//				"|write|1000000|files of size|10KB|using|80|threads|",
//				Constants.LINE_SEPARATOR);
//
//		EasyMock.expect(loader.readPageFile(getFullPath( name))).andReturn(SimpleLoadList);
//		EasyMock.expect(loader.readPageFile(getFullPath(SET_UP))).andThrow(
//				new FileNotFoundException(""));
//		EasyMock.expect(loader.readPageFile(getFullPath( TEAR_DOWN)))
//				.andReturn(SimpleTearnDown);
//		EasyMock.replay(loader);
//		Page page = m_handler.loadPage(name);
//
//		assertEquals(3, page.countPageElements());
//		assertEquals(PageElementType.TABLE, page.getElement(0).getType());
//		assertEquals("|set node regeneration submit delay|30 min|"
//				+ Constants.LINE_SEPARATOR, PageUtils
//				.tableToString((Table) page.getElement(0)));
//
//		assertEquals(PageElementType.TABLE, page.getElement(1).getType());
//
//		assertEquals("|with cubetools|" + Constants.LINE_SEPARATOR
//				+ "|write|10|files of size|10KB|using|10|threads|"
//				+ Constants.LINE_SEPARATOR, PageUtils
//				.tableToString((Table) page.getElement(1)));
//		assertEquals(PageElementType.TEAR_DOWN, page.getElement(2).getType());
//		TearDown setUpinclude = (TearDown) page.getElement(2);
//		Page pageSetUp = setUpinclude.getPage();
//		assertEquals(1, pageSetUp.countPageElements());
//		EasyMock.verify(loader);
//	}
//
//	@Test
//	public void testLoadRecursiveInclude() throws IOException {
//		List<String> pageList1 = CollectionUtils.list(
//				"|set node regeneration submit delay|30 min|",
//				Constants.LINE_SEPARATOR, "|with cubetools|",
//				"|write|10|files of size|10KB|using|10|threads|",
//				Constants.LINE_SEPARATOR, "!include .TestPage2");
//		List<String> pageList2 = CollectionUtils.list("!include .TestPage1");
//		String pageName1 = "TestPage1";
//
//		String pageName2 = ".TestPage2";
//
//		EasyMock.expect(loader.readPageFile(getFullPath( pageName1))).andReturn(pageList1);
//		EasyMock.expect(loader.readPageFile(getFullPath( SET_UP))).andThrow(
//				new FileNotFoundException(""));
//		EasyMock.expect(loader.readPageFile(getFullPath( TEAR_DOWN))).andThrow(
//				new FileNotFoundException(""));
//		EasyMock.expect(loader.readPageFile(getFullPath( pageName2))).andReturn(pageList2);
//		EasyMock.replay(loader);
//		Page page = m_handler.loadPage(pageName1);
//		// System.err.println(page.countPageElements());
//
//		assertEquals(3, page.countPageElements());
//		assertEquals("|set node regeneration submit delay|30 min|"
//				+ Constants.LINE_SEPARATOR, PageUtils
//				.tableToString((Table) page.getElement(0)));
//		assertEquals("|with cubetools|" + Constants.LINE_SEPARATOR
//				+ "|write|10|files of size|10KB|using|10|threads|"
//				+ Constants.LINE_SEPARATOR, PageUtils
//				.tableToString((Table) page.getElement(1)));
//		assertEquals(PageElementType.INCLUDE_ERROR, page.getElement(2)
//				.getType());
//		EasyMock.verify(loader);
//	}
//
//	@Test
//	public void testLoadNotExistingInclude() throws IOException {
//		List<String> SimpleLoadList = CollectionUtils.list(
//				"|set node regeneration submit delay|30 min|",
//				Constants.LINE_SEPARATOR, "|with cubetools|",
//				"|write|10|files of size|10KB|using|10|threads|",
//				Constants.LINE_SEPARATOR, "!include .NotExistingInclude");
//		String name = "SimPlePage";
//
//		EasyMock.expect(loader.readPageFile(getFullPath(name))).andReturn(SimpleLoadList);
//		EasyMock.expect(loader.readPageFile(getFullPath(SET_UP))).andThrow(
//				new FileNotFoundException(""));
//		EasyMock.expect(loader.readPageFile(getFullPath( TEAR_DOWN))).andThrow(
//				new FileNotFoundException(""));
//		EasyMock.expect(loader.readPageFile( getFullPath(".NotExistingInclude"))).andThrow(
//				new FileNotFoundException(""));
//		EasyMock.replay(loader);
//		Page page = m_handler.loadPage(name);
//		// System.err.println(page.countPageElements());
//
//		assertEquals(3, page.countPageElements());
//		assertEquals("|set node regeneration submit delay|30 min|"
//				+ Constants.LINE_SEPARATOR, PageUtils
//				.tableToString((Table) page.getElement(0)));
//		assertEquals("|with cubetools|" + Constants.LINE_SEPARATOR
//				+ "|write|10|files of size|10KB|using|10|threads|"
//				+ Constants.LINE_SEPARATOR, PageUtils
//				.tableToString((Table) page.getElement(1)));
//		assertEquals(PageElementType.INCLUDE_ERROR, page.getElement(2)
//				.getType());
//		EasyMock.verify(loader);
//	}
//
//
//	@Test
//	public void testLoadPageWithContent() throws IOException{
//	  List<String> SimpleLoadList = CollectionUtils.list(
//        "|set node regeneration submit delay|30 min|",
//        Constants.LINE_SEPARATOR, "|with cubetools|",
//        "|write|10|files of size|10KB|using|10|threads|", "!contents -R2"
//        );
//    String name = "SimPlePage";
//
//    EasyMock.expect(loader.readPageFile(getFullPath(name))).andReturn(SimpleLoadList);
//    EasyMock.expect(loader.readPageFile(getFullPath(SET_UP))).andThrow(
//        new FileNotFoundException(""));
//    EasyMock.expect(loader.readPageFile(getFullPath(TEAR_DOWN))).andThrow(
//        new FileNotFoundException(""));
//    Content content = new Content(2);
//
//    EasyMock.expect(creator.createContent(root, name, 2)).andReturn(content);
//
//    EasyMock.replay(loader, creator);
//
//    Page page = m_handler.loadPage(name);
//    EasyMock.verify(loader,creator);
//
//    assertEquals(3, page.countPageElements());
//    assertEquals("|set node regeneration submit delay|30 min|"
//        + Constants.LINE_SEPARATOR, PageUtils
//        .tableToString((Table) page.getElement(0)));
//    assertEquals("|with cubetools|" + Constants.LINE_SEPARATOR
//        + "|write|10|files of size|10KB|using|10|threads|"
//        + Constants.LINE_SEPARATOR, PageUtils
//        .tableToString((Table) page.getElement(1)));
//    assertEquals(content, page.getElement(2));
//	}
//
//	@Test
//	public void testContentInInclude() throws IOException{
//	  List<String> SimpleLoadList = CollectionUtils.list(
//	      "!include .PageWithContent");
//    String name = "SimPlePage";
//
//    List<String> PageWithContentList = CollectionUtils.list(
//    "!contents -R3");
//
//    EasyMock.expect(loader.readPageFile(getFullPath( name))).andReturn(SimpleLoadList);
//    EasyMock.expect(loader.readPageFile(getFullPath(SET_UP))).andThrow(
//        new FileNotFoundException(""));
//    EasyMock.expect(loader.readPageFile(getFullPath(TEAR_DOWN))).andThrow(
//        new FileNotFoundException(""));
//
//    EasyMock.expect(loader.readPageFile(getFullPath(".PageWithContent"))).andReturn(PageWithContentList);
//
//    Content content = new Content(3);
//    EasyMock.expect(creator.createContent(root, ".PageWithContent", 3)).andReturn(content);
//
//    EasyMock.replay(loader, creator);
//
//    Page page = m_handler.loadPage(name);
//    EasyMock.verify(loader, creator);
//
//    assertEquals(1, page.countPageElements());
//    Include include = (Include)page.getElement(0);
//    assertEquals(1, include.getPage().countPageElements());
//    assertEquals(content, include.getPage().getElement(0));
//	}

	private String getFullPath(String pagePath){
	  return PageUtils.getFullPath(root, pagePath);
	}
}
